package com.spring.component.redis;

import com.spring.component.utils.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author liushihua
 * @since 2018年02月26日
 */
@Configuration
public class RedisConfig {

  @Autowired
  private RedisProperties redisProperties;

  @Bean
  public RedisClusterConfiguration redisClusterConfiguration() {
    RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
    redisClusterConfiguration.setClusterNodes(getRedisNode());
    redisClusterConfiguration.setMaxRedirects(redisProperties.getMaxRedirects());
    return redisClusterConfiguration;
  }

  @Bean
  public JedisPoolConfig jedisPoolConfig() {
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxIdle(redisProperties.getMaxIdle());
    jedisPoolConfig.setMaxTotal(redisProperties.getMaxTotal());
    jedisPoolConfig.setMinIdle(redisProperties.getMinIdle());
    jedisPoolConfig.setMaxWaitMillis(redisProperties.getMaxWaitMillis());
    jedisPoolConfig.setNumTestsPerEvictionRun(redisProperties.getNumTestsPerEvictionRun());
    jedisPoolConfig
        .setTimeBetweenEvictionRunsMillis(redisProperties.getTimeBetweenEvictionRunsMillis());
    jedisPoolConfig.setTestOnBorrow(redisProperties.isTestOnBorrow());
    return jedisPoolConfig;
  }

  @Bean
  public JedisConnectionFactory jedisConnectionFactory(
      RedisClusterConfiguration redisClusterConfiguration, JedisPoolConfig jedisPoolConfig) {
    JedisConnectionFactory jedisConnectionFactory =
        new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
    jedisConnectionFactory.setTimeout(redisProperties.getTimeout());
    return jedisConnectionFactory;
  }

  @Bean
  public RedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(jedisConnectionFactory);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
    // redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    return redisTemplate;
  }

  private List<RedisNode> getRedisNode() {
    List<String> nodes = redisProperties.getNodes();
    if (CommonUtils.isNotEmpty(nodes)) {
      List<RedisNode> redisNodes = nodes.stream().map(node -> {
        String[] ss = node.split(":");
        return new RedisNode(ss[0], Integer.valueOf(ss[1]));
      }).collect(Collectors.toList());
      return redisNodes;
    }
    return new ArrayList<>();
  }
}
